package com.ruoyi.web.controller.project;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.math.NumberUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.project.domain.ProProcess;
import com.ruoyi.project.domain.ProProject;
import com.ruoyi.project.service.IProProcessService;
import com.ruoyi.project.service.IProProjectService;

/**
 * 项目进度Controller
 * 
 * @author phil
 * @date 2020-06-02
 */
@Controller
@RequestMapping("/project/process")
public class ProProcessController extends BaseController{
	private String prefix = "project/process";

	@Autowired
	private IProProcessService proProcessService;
	@Autowired
	private IProProjectService proProjectService;

	@RequiresPermissions("project:process:view")
	@GetMapping()
	public String process(){
		return prefix + "/process";
	}

	/**
	 * 查询项目进度列表
	 */
	@RequiresPermissions("project:process:list")
	@PostMapping("/list")
	@ResponseBody
	public TableDataInfo list(ProProcess proProcess){
		startPage();
		List<ProProcess> list = proProcessService.selectProProcessList(proProcess);
		return getDataTable(list);
	}

	/**
	 * 导出项目进度列表
	 */
	@RequiresPermissions("project:process:export")
	@Log(title = "项目进度", businessType = BusinessType.EXPORT)
	@PostMapping("/export")
	@ResponseBody
	public AjaxResult export(ProProcess proProcess){
		List<ProProcess> list = proProcessService.selectProProcessList(proProcess);
		ExcelUtil<ProProcess> util = new ExcelUtil<ProProcess>(ProProcess.class);
		return util.exportExcel(list, "process");
	}

	/**
	 * 新增项目进度
	 */
	@GetMapping("/add")
	public String add(){
		return prefix + "/add";
	}

	/**
	 * 新增保存项目进度
	 */
	@RequiresPermissions("project:process:add")
	@Log(title = "项目进度", businessType = BusinessType.INSERT)
	@PostMapping("/add")
	@ResponseBody
	public AjaxResult addSave(ProProcess proProcess){
		return toAjax(proProcessService.insertProProcess(proProcess));
	}

	/**
	 * 修改项目进度
	 */
	@GetMapping("/edit/{processId}")
	public String edit(@PathVariable("processId") Long processId, ModelMap mmap){
		ProProcess proProcess = proProcessService.selectProProcessById(processId);
		mmap.put("proProcess", proProcess);
		return prefix + "/edit";
	}

	/**
	 * 修改保存项目进度
	 */
	@RequiresPermissions("project:process:edit")
	@Log(title = "项目进度", businessType = BusinessType.UPDATE)
	@PostMapping("/edit")
	@ResponseBody
	public AjaxResult editSave(ProProcess proProcess){
		return toAjax(proProcessService.updateProProcess(proProcess));
	}

	/**
	 * 删除项目进度
	 */
	@RequiresPermissions("project:process:remove")
	@Log(title = "项目进度", businessType = BusinessType.DELETE)
	@PostMapping("/remove")
	@ResponseBody
	public AjaxResult remove(String ids){
		return toAjax(proProcessService.deleteProProcessByIds(ids));
	}

	/**
	 * 下载导入模板
	 * 
	 * @return
	 */
	@RequiresPermissions("project:process:importTemplate")
	@GetMapping("/importTemplate")
	@ResponseBody
	public AjaxResult importTemplate(){
		ExcelUtil<ProProcess> util = new ExcelUtil<ProProcess>(ProProcess.class);
		return util.importTemplateExcel("项目数据");
	}

	/**
	 * 项目导入
	 * 
	 * @param file
	 * @param updateSupport
	 * @return
	 * @throws Exception
	 */
	@RequiresPermissions("project:process:import")
	@PostMapping("/importData")
	@ResponseBody
	public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception{
		ExcelUtil<ProProcess> util = new ExcelUtil<ProProcess>(ProProcess.class);
		List<ProProcess> processList = util.importExcel(file.getInputStream());
		// 格式校验
		String operName = ShiroUtils.getSysUser().getLoginName();
		String message = importProcess(processList, updateSupport, operName);
		return AjaxResult.success(message);
	}

	/**
	 * 导入项目进度
	 * 
	 * @param processList
	 * @param isUpdateSupport
	 * @param operName
	 * @return
	 */
	public String importProcess(List<ProProcess> processList, boolean isUpdateSupport, String operName) throws Exception{
		if(StringUtils.isNull(processList) || processList.size() == 0){
			throw new BusinessException("导入项目进度数据不能为空！");
		}

		// 查询已有项目列表
		List<ProProject> oldProjectList = proProjectService.selectProProjectList(new ProProject());

		// 查询已有项目进度
		List<ProProcess> oldProcessList = proProcessService.selectProProcessList(new ProProcess());

		int failureNum = 0;
		int rowNum = 1; // 起始行数
		StringBuilder successMsg = new StringBuilder();
		StringBuilder failureMsg = new StringBuilder();
		for(ProProcess process : processList){
			rowNum++;

			// 里程碑名称校验
			String processName = process.getProcessName();
			if(StringUtils.isEmpty(processName)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，里程碑名称不允许为空");
			}else{
				// 验证同一项目下，是否存在相同的里程碑名称
				boolean hasFlag = checkHasProcessName(processName, oldProcessList);
				if(hasFlag){
					failureNum++;
					failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，里程碑名称在系统已存在");
				}
			}

			// 是否超期校验
			String isOverdue = process.getIsOverdue();
			if(StringUtils.isEmpty(isOverdue)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，是否超期不允许为空");
			}else{
				int flag = NumberUtils.toInt(isOverdue, -1);
				if(flag == -1){
					failureNum++;
					failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，是否超期:" + isOverdue + "在码表不存在");
				}
			}

			// 超期时长校验
			Integer overdueDuration = process.getOverdueDuration();
			if("0".equals(isOverdue) && overdueDuration != 0){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，是否超期为否时，超期时长需为0");
			}else if("1".equals(isOverdue) && overdueDuration > 0){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，是否超期为是时，超期时长需大于0");
			}

			/*
			 * // 立项时间 Date approvalTime = process.getApprovalTime(); if(StringUtils.isEmpty(approvalTime.toString())){ failureNum++; failureMsg.append("<br/>" + failureNum + "、第" + rowNum +
			 * "行，立项时间不允许为空"); }
			 * 
			 * // 当前时间 Date currentTime = process.getCurrentTime(); if(StringUtils.isEmpty(currentTime.toString())){ failureNum++; failureMsg.append("<br/>" + failureNum + "、第" + rowNum +
			 * "行，当前时间不允许为空"); }
			 */

			// 项目名称
			String proName = process.getProName();
			if(StringUtils.isEmpty(proName)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目名称不允许为空");
			}

			// 根据项目名称查询项目ID
			Long proId = selectProIdByName(proName, oldProjectList);
			if(proId == null){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目名称：" + proName + "在系统不存在");
			}else{
				process.setProId(proId);
			}

			process.setCreateTime(new Date());
			process.setCreateBy(operName);
		}

		if(failureNum > 0){
			failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 处数据格式不正确，错误如下：");
			throw new BusinessException(failureMsg.toString());
		}else{
			// 插入项目数据
			int successNum = proProcessService.insertProProcess(processList);
			successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
		}
		return successMsg.toString();
	}

	/**
	 * 检查里程碑名称是否存在
	 * 
	 * @param processName 里程碑名称
	 * @param oldProcessList 已有里程碑列表
	 * @return
	 */
	private boolean checkHasProcessName(String processName, List<ProProcess> oldProcessList){
		boolean hasFlag = false;
		if(oldProcessList != null && oldProcessList.size() > 0 && processName != null && !"".equals(processName)){
			for(ProProcess process : oldProcessList){
				if(processName.trim().equals(process.getProcessName())){
					hasFlag = true;
					break;
				}
			}
		}
		return hasFlag;
	}

	/**
	 * 通过项目名称查询项目ID
	 * 
	 * @return
	 */
	public Long selectProIdByName(String proName, List<ProProject> proList){
		Long proId = null;
		if(proList != null && proList.size() > 0){
			for(ProProject pro : proList){
				if(proName.trim().equals(pro.getProjectName())){
					proId = pro.getProjectId();
					break;
				}
			}
		}
		return proId;
	}
}
